package com.ruoyi.learn.java.design.pattern.behavior;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

// ============== 访问者接口 (Visitor) ==============
interface DocumentElementVisitor {
    void visit(TextElement textElement);
    void visit(ImageElement imageElement);
}

// ============== 元素接口 (Element) ==============
interface DocumentElement {
    void accept(DocumentElementVisitor visitor);
}

// ============== 具体元素 (ConcreteElement) ==============

// 文本元素
class TextElement implements DocumentElement {
    private String content;

    public TextElement(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }

    @Override
    public void accept(DocumentElementVisitor visitor) {
        visitor.visit(this);
    }
}

// 图片元素
class ImageElement implements DocumentElement {
    private String imageUrl;
    private String altText;

    public ImageElement(String imageUrl, String altText) {
        this.imageUrl = imageUrl;
        this.altText = altText;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public String getAltText() {
        return altText;
    }

    @Override
    public void accept(DocumentElementVisitor visitor) {
        visitor.visit(this);
    }
}

// ============== 具体访问者 (ConcreteVisitor) ==============

// HTML导出访问者
class HtmlExportVisitor implements DocumentElementVisitor {
    private StringBuilder htmlContent = new StringBuilder();

    @Override
    public void visit(TextElement textElement) {
        htmlContent.append("<p>").append(textElement.getContent()).append("</p>\n");
    }

    @Override
    public void visit(ImageElement imageElement) {
        htmlContent.append("<img src=\"").append(imageElement.getImageUrl())
                .append("\" alt=\"").append(imageElement.getAltText()).append("\" />\n");
    }

    public String getHtmlContent() {
        return htmlContent.toString();
    }
}

// 文本统计访问者
class TextStatisticsVisitor implements DocumentElementVisitor {
    private int totalTextLength = 0;
    private int wordCount = 0;

    @Override
    public void visit(TextElement textElement) {
        String content = textElement.getContent();
        totalTextLength += content.length();
        wordCount += content.trim().isEmpty() ? 0 : content.trim().split("\\s+").length;
    }

    @Override
    public void visit(ImageElement imageElement) {
        // 图片不贡献文本长度和单词数
    }

    public int getTotalTextLength() {
        return totalTextLength;
    }

    public int getWordCount() {
        return wordCount;
    }
}

// 拼写检查访问者 (简化版)
class SpellCheckVisitor implements DocumentElementVisitor {
    private int errorCount = 0;
    // 简单的词典
    // 简单的词典 - 使用兼容 Java 8 的方式初始化
    private Set<String> dictionary = new HashSet<String>() {{
        add("hello");
        add("world");
        add("java");
        add("design");
        add("pattern");
        add("visitor");
        add("is");
        add("a");
    }};
    @Override
    public void visit(TextElement textElement) {
        String[] words = textElement.getContent().toLowerCase().split("\\s+");
        for (String word : words) {
            word = word.replaceAll("[^a-zA-Z]", "").toLowerCase();
            if (!word.isEmpty() && !dictionary.contains(word)) {
                System.out.println("拼写错误: '" + word + "'");
                errorCount++;
            }
        }
    }

    @Override
    public void visit(ImageElement imageElement) {
        // 图片无需拼写检查
    }

    public int getErrorCount() {
        return errorCount;
    }
}

// ============== 对象结构 (ObjectStructure) ==============
class Document {
    private List<DocumentElement> elements = new ArrayList<>();

    public void addElement(DocumentElement element) {
        elements.add(element);
    }

    // 接受访问者，遍历所有元素
    public void accept(DocumentElementVisitor visitor) {
        for (DocumentElement element : elements) {
            element.accept(visitor);
        }
    }
}

// ============== 主类 (Client) ==============
public class VisitorPattern {
    public static void main(String[] args) {
        // 创建文档对象结构
        Document document = new Document();

        // 添加具体元素
        document.addElement(new TextElement("Hello world! This is a Java design pattern example."));
        document.addElement(new ImageElement("https://example.com/image1.jpg", "Design Pattern"));
        document.addElement(new TextElement("Visitor pattern is powerful."));
        document.addElement(new ImageElement("https://example.com/image2.png", "UML Diagram"));

        // --- 使用 HTML 导出访问者 ---
        HtmlExportVisitor htmlVisitor = new HtmlExportVisitor();
        document.accept(htmlVisitor);
        System.out.println("=== 生成的HTML ===");
        System.out.println(htmlVisitor.getHtmlContent());

        // --- 使用 文本统计访问者 ---
        TextStatisticsVisitor statsVisitor = new TextStatisticsVisitor();
        document.accept(statsVisitor);
        System.out.println("=== 文本统计 ===");
        System.out.println("总文本长度: " + statsVisitor.getTotalTextLength());
        System.out.println("单词数量: " + statsVisitor.getWordCount());

        // --- 使用 拼写检查访问者 ---
        SpellCheckVisitor spellCheckVisitor = new SpellCheckVisitor();
        System.out.println("\n=== 拼写检查结果 ===");
        document.accept(spellCheckVisitor);
        System.out.println("发现拼写错误: " + spellCheckVisitor.getErrorCount() + " 处");
    }
}